﻿using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using Shipeng.Util;
using SqlSugar;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using Yitter.IdGenerator;
using YNTK.Common.Const;
using YNTK.Common.Enum;
using YNTK.Common.Filter;
using YNTK.Data.MongoDB.Repositorie;
using YNTK.Dependency;
using YNTK.DynamicApiController;
using YNTK.EIMS.Entitys.Suppliers;
using YNTK.EIMS.Interface;
using YNTK.FriendlyException;
using YNTK.LinqBuilder;
using YNTK.Mapster;
using YNTK.System.Entitys.Dto.Common;
using YNTK.System.Entitys.Permission;
using YNTK.System.Interfaces.Common;
using YNTK.System.Interfaces.Permission;
using YNTK.System.Interfaces.Resources;

namespace YNTK.EIMS
{
    /// <summary>
    /// 供应商服务的实现
    /// 版 本：V1.0.0.0
    /// 版 权：云南通科科技有限公司（https://www.yntkkj.com）
    /// 作 者：李仕鹏
    /// 日 期：2022.11.15
    /// </summary>
    [ApiDescriptionSettings(Tag = "供应商服务", Name = "Suppliers", Order = 780)]
    [Route("api/[controller]")]
    public class SupplierService : ISupplierService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<SuppliersEntity> _repository;//供应商仓储
        private readonly IMongoDBRepository<SuppliersEntity> _mongoDbRepository;//供应商mongodb仓储
        private readonly ISqlSugarRepository<SupplierFilesEntity> _fileRepository;//供应商相关附件仓储
        private readonly IMongoDBRepository<SupplierFilesEntity> _fileMongoDbRepository;//供应商相关附件mongodb仓储
        private readonly ISqlSugarRepository<SupplierProductLibraryEntity> _productRepository;//供应商产品库仓储
        private readonly IMongoDBRepository<SupplierProductLibraryEntity> _productMongoDbRepository;//供应商产品库mongodb仓储
        private readonly ISqlSugarRepository<SupplierProductLibraryDetailEntity> _productDetailRepository;//供应商产品详情仓储
        private readonly IMongoDBRepository<SupplierProductLibraryDetailEntity> _productDetailMongoDbRepository;//供应商产品详情mongodb仓储
        private readonly ISqlSugarRepository<SupplierEvaluateEntity> _evaluateRepository;//供应商评价仓储
        private readonly IMongoDBRepository<SupplierEvaluateEntity> _evaluatemongoDbRepository;//供应商评价mongodb仓储

        private readonly IMechanismService _mechanismService;//机构服务
        private readonly ITkUsersService _tkUsersService;//用户服务
        private readonly IDictionaryService _dictionaryService;//字典服务
        private readonly IFileService _fileService;//文件服务
        private readonly ITkRoleService _tkRoleService;//角色服务
        private readonly HttpContext _httpContext;

        private readonly string _suppliers = "eims_suppliers";//mongodb中供应商数据集名称
        private readonly string _supplier_evaluates = "eims_supplier_evaluates";//mongodb中供应商评价数据集名称
        private readonly string _supplierfiles = "eims_supplierfiles";//mongodb中供应商相关附件数据集名称
        private readonly string _productlibrary = "eims_supplier_productlibrary";//mongodb中供应商产品库数据集名称
        private readonly string _productlibrary_details = "eims_supplier_productlibrary_details";//mongodb中供应商产品详情数据集名称

        /// <summary>
        /// 构造方法依赖注入
        /// </summary>
        /// <param name="repository">供应商仓储</param>
        /// <param name="mongoDbRepository">供应商mongodb仓储</param>
        /// <param name="fileRepository">供应商相关附件仓储</param>
        /// <param name="fileMongoDbRepository">供应商相关附件mongodb仓储</param>
        /// <param name="productRepository">供应商产品库仓储</param>
        /// <param name="productMongoDbRepository">供应商产品库mongodb仓储</param>
        /// <param name="productDetailRepository">供应商产品详情仓储</param>
        /// <param name="productDetailMongoDbRepository">供应商产品详情mongodb仓储</param>
        /// <param name="evaluateRepository">供应商评价仓储</param>
        /// <param name="evaluatemongoDbRepository">供应商评价mongodb仓储</param>
        /// <param name="mechanismService">机构服务</param>
        /// <param name="tkUsersService">用户m服务</param>
        /// <param name="dictionaryService">字典服务</param>
        /// <param name="fileService">文件服务</param>
        /// <param name="tkRoleService">角色服务</param>
        public SupplierService(ISqlSugarRepository<SuppliersEntity> repository,
            IMongoDBRepository<SuppliersEntity> mongoDbRepository,
            ISqlSugarRepository<SupplierFilesEntity> fileRepository,
            IMongoDBRepository<SupplierFilesEntity> fileMongoDbRepository,
            ISqlSugarRepository<SupplierProductLibraryEntity> productRepository,
            IMongoDBRepository<SupplierProductLibraryEntity> productMongoDbRepository,
            ISqlSugarRepository<SupplierProductLibraryDetailEntity> productDetailRepository,
            IMongoDBRepository<SupplierProductLibraryDetailEntity> productDetailMongoDbRepository,
            ISqlSugarRepository<SupplierEvaluateEntity> evaluateRepository,
            IMongoDBRepository<SupplierEvaluateEntity> evaluatemongoDbRepository,
            IMechanismService mechanismService, ITkUsersService tkUsersService,
            IDictionaryService dictionaryService, IFileService fileService, ITkRoleService tkRoleService)
        {
            _repository = repository;
            _mongoDbRepository = mongoDbRepository;
            _fileRepository = fileRepository;
            _fileMongoDbRepository = fileMongoDbRepository;
            _productRepository = productRepository;
            _productMongoDbRepository = productMongoDbRepository;
            _productDetailRepository = productDetailRepository;
            _productDetailMongoDbRepository = productDetailMongoDbRepository;
            _evaluateRepository = evaluateRepository;
            _evaluatemongoDbRepository = evaluatemongoDbRepository;

            _mechanismService = mechanismService;
            _tkUsersService = tkUsersService;
            _dictionaryService = dictionaryService;
            _fileService = fileService;
            _tkRoleService = tkRoleService;
            _httpContext = App.HttpContext;
        }

        #region 供应商
        /// <summary>
        /// 获取供应商下拉数据(只获取启用的),查询全部：“api/suppliers/selects/null/null”
        /// </summary>
        /// <param name="mechanismId">机构id</param>
        /// <param name="classifyId">供应商分类id</param>
        /// <returns></returns>
        [HttpGet("selects/{mechanismId}/{classifyId}")]
        public async Task<TkResult<List<SupplierSelectDto>>> GetSelect(string mechanismId, string classifyId)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string curMechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
                string roleId = user.Subject.FindFirst(ClaimConst.ROLEID).Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                #region 拼接查询条件
                Expression<Func<SuppliersEntity, bool>> where = m => 
                m.OrganizeId == organizeId && m.EnabledMark == 1 && m.DeleteMark == null;
                if (authenticationType == "2")
                    where = where.And(m => m.OrganizeId == organizeId && (
                    (m.CreatorUserId != userId && m.SharedScope != 4) || m.CreatorUserId == userId));
                else
                {
                    where = where.And(m => m.CreatorUserId == userId ||
                   (m.SharedScope == 0 && m.OrganizeId == organizeId) ||
                   (m.SharedScope == 1 && m.MechanismId == curMechanismId) ||
                   (m.SharedScope == 2 && m.SharedScopeValue.Contains(roleId)) ||
                   (m.SharedScope == 3 && m.SharedScopeValue.Contains(userId)));
                }

                if (!string.IsNullOrWhiteSpace(mechanismId))
                {
                    string queryMechanismId = await _mechanismService.GetIdAsync(mechanismId, organizeId);
                    where = where.And(m => m.MechanismId == queryMechanismId);
                }
                if (!string.IsNullOrWhiteSpace(classifyId))
                {
                    string queryClassifyId = await _dictionaryService.GetIdAsync(classifyId, organizeId);
                    where = where.And(m => m.ClassifyId == queryClassifyId);
                }
                #endregion

                var data = await GetSupplierListAsync(where);
                var result = data.Adapt<List<SupplierSelectDto>>();
                return TkResult<List<SupplierSelectDto>>.Success(result);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"获取供应商下拉数据发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 分页获取供应商数据
        /// </summary>
        /// <param name="query">查询供应商请求模型</param>
        /// <returns></returns>
        [HttpPost("gets")]
        public async Task<TkPageResult<SupplierListDto>> Gets([FromBody] QuerySupplierFilterRequestModel query)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
                string roleId = user.Subject.FindFirst(ClaimConst.ROLEID).Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                #region 拼接查询条件
                Expression<Func<SuppliersEntity, bool>> where = m =>m.OrganizeId== organizeId && m.DeleteMark == null;
                if (authenticationType == "2")
                    where = where.And(m => m.OrganizeId == organizeId && (
                    (m.CreatorUserId != userId && m.SharedScope != 4) || m.CreatorUserId == userId));
                else
                {
                    where = where.And(m => m.CreatorUserId == userId ||
                   (m.SharedScope == 0 && m.OrganizeId == organizeId && m.EnabledMark == 1) ||
                   (m.SharedScope == 1 && m.MechanismId == mechanismId && m.EnabledMark == 1) ||
                   (m.SharedScope == 2 && m.SharedScopeValue.Contains(roleId) && m.EnabledMark == 1) ||
                   (m.SharedScope == 3 && m.SharedScopeValue.Contains(userId) && m.EnabledMark == 1));
                }

                if (query.enabledMark == 1) where = where.And(m => m.EnabledMark == 1);
                if (query.enabledMark == 0) where = where.And(m => m.EnabledMark != 1);
                if (!string.IsNullOrWhiteSpace(query.mechanismId))
                {
                    string queryMechanismId = await _mechanismService.GetIdAsync(query.mechanismId, organizeId);
                    where = where.And(m => m.MechanismId == queryMechanismId);
                }
                if (!string.IsNullOrWhiteSpace(query.classifyId))
                {
                    string queryClassifyId = await _dictionaryService.GetIdAsync(query.classifyId, organizeId);
                    where = where.And(m => m.ClassifyId == queryClassifyId);
                }
                if (query.sharedScope != null)
                    where = where.And(m => m.SharedScope == query.sharedScope.GetHashCode());
                if (query.startTime != null) where = where.And(m => m.CreatorTime >= query.startTime);
                if (query.endTime != null) where = where.And(m => m.CreatorTime <= query.endTime);
                if (!string.IsNullOrWhiteSpace(query.keyword))
                    where = where.And(m => m.SupplierName.Contains(query.keyword) ||
                    m.SupplierNo.Contains(query.keyword) || m.Contact.Contains(query.keyword) ||
                    m.ContactWay.Contains(query.keyword) || m.Address.Contains(query.keyword) ||
                    m.Description.Contains(query.keyword));
                #endregion

                var pageList = new SqlSugarPagedList<SupplierListDto>();

                #region 先从mongodb中获取供应商数据
                //排序生成器
                var builderSort = Builders<SuppliersEntity>.Sort;
                //排序约束   Ascending 正序    Descending 倒序
                var sort = builderSort.Ascending(r => r.SortCode).Descending(r => r.CreatorTime);
                //Item1.结果集 Item2.总条数 Item3.总页数
                (List<SuppliersEntity>, int, int) result =
                    await _mongoDbRepository.GetListAsync(_suppliers,
                    where, query.currentPage, query.pageSize, null, sort);
                pageList.list = result.Item1.Adapt<List<SupplierListDto>>();
                pageList.pagination = new PagedModel()
                {
                    PageIndex = query.currentPage,
                    PageSize = query.pageSize,
                    Total = result.Item2,
                    PageCount = result.Item3
                };
                #endregion

                if (!pageList.list.Any())
                {
                    #region 再从sqlserver中获取供应商数据
                    var sqlResult = await _repository.Entities.Where(where)
                        .OrderBy(r => r.SortCode, OrderByType.Asc)
                        .OrderBy(r => r.CreatorTime, OrderByType.Desc)
                        .ToPagedListAsync(query.currentPage, query.pageSize);
                    pageList.list = sqlResult.list.Adapt<List<SupplierListDto>>();
                    pageList.pagination = sqlResult.pagination;
                    #endregion
                }

                #region 处理供应商返回数据
                if (pageList.list.Any())
                {
                    var mechanismIds = pageList.list.Where(r => !string.IsNullOrWhiteSpace(r.mechanismId))
                        ?.Select(r => r.mechanismId.Split(',').ToList())
                        ?.SelectMany(r => r).Distinct().ToList();
                    var mechanisms = !mechanismIds.Any() ? new List<MechanismEntity>() :
                        await _mechanismService.GetMechanismListAsync(null, mechanismIds);
                    var classifyIds = pageList.list.Select(r => r.classifyId.Split(',').ToList())
                       .SelectMany(r => r).Distinct().ToList();
                    var classifys = await _dictionaryService.GetDictionaryListByIds(classifyIds);
                    var userIds = pageList.list.Select(r => r.creatorUserId).Distinct().ToList();
                    var users = await _tkUsersService.GetUserListByIds(userIds);
                    pageList.list.ForEach(item =>
                    {
                        item.sharedScopeText = EnumHelper.GetEnumDescriptionString
                        (item.sharedScope, typeof(SharedScopeEnum));
                        if (!string.IsNullOrWhiteSpace(item.mechanismId))
                        {
                            item.mechanismName = mechanisms?.FirstOrDefault(r => r.Id == item.mechanismId.Split(',').Last())?.Name;
                        }
                        if (!string.IsNullOrWhiteSpace(item.classifyId))
                        {
                            item.classifyName = classifys?.FirstOrDefault(r => r.Id == item.classifyId.Split(',').Last())?.Name;
                        }
                        item.creatorUserName = users?.FirstOrDefault(r => r.Id == item.creatorUserId)?.RealName;
                    });
                }
                #endregion

                return TkPageResult<SupplierListDto>.Success(pageList);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"分页获取供应商数据发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 获取供应商详细信息
        /// </summary>
        /// <param name="id">供应商id</param>
        /// <returns></returns>
        [HttpGet("get/{id}")]
        public async Task<TkResult<SupplierInfoDto>> Get([Required] string id)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                var entity = await GetSupplierInfoAsync(r => r.Id == id && r.DeleteMark == null);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0001);

                var result = entity.Adapt<SupplierInfoDto>();

                #region 处理供应商返回信息
                result.sharedScopeText = EnumHelper.GetEnumDescriptionString
                        (result.sharedScope, typeof(SharedScopeEnum));
                if (!string.IsNullOrWhiteSpace(result.mechanismId) && result.mechanismId != "jg000000")
                {
                    result.mechanismName = string.Join('/', (await _mechanismService
                        .GetMechanismListAsync(null, result.mechanismId.Split(',').ToList()))
                        ?.Select(r => r.Name)?.ToList());
                }
                if (!string.IsNullOrWhiteSpace(result.classifyId))
                {
                    result.classifyName = string.Join('/', (await _dictionaryService
                   .GetDictionaryListByIds(result.classifyId.Split(',').ToList()))
                   ?.Select(r => r.Name)?.ToList());
                }
                #region 处理共享范围
                if (!string.IsNullOrWhiteSpace(result.sharedScopeValue))
                {
                    //共享范围(0.全组织 1.特定机构 2.特定角色 3.特定用户 4.仅自己可见)
                    switch (result.sharedScope)
                    {
                        case 0:
                            result.sharedScopeValueText = "全组织";
                            break;
                        case 1:
                            var dic = await _mechanismService.GetIdsAsync(result.sharedScopeValue.Split(',').ToList(), organizeId);
                            var values = dic.Values.ToList();
                            result.sharedScopeValueText = string.Join(',', values.Select(r => r.Item2).ToList());
                            result.sharedScopeMechanismValue = values.Select(r => r.Item1.Split(',').ToArray())?.ToList();
                            break;
                        case 2:
                            result.sharedScopeValueText = string.Join(',', (await _tkRoleService
                                .GetTkRoleListByIdsAsync(result.sharedScopeValue.Split(',').ToList()))
                                ?.Select(r => r.Name)?.ToList());
                            break;
                        case 3:
                            result.sharedScopeValueText = string.Join(',', (await _tkUsersService
                               .GetUserListByIds(result.sharedScopeValue.Split(',').ToList()))
                               ?.Select(r => r.RealName)?.ToList());
                            break;
                        case 4:
                            result.sharedScopeValueText = "仅自己可见";
                            break;
                    }
                }
                #endregion
                if (!string.IsNullOrWhiteSpace(result.creatorUserId))
                    result.creatorUserName = (await _tkUsersService.GetUserInfoByUserId(result.creatorUserId))?.RealName;
                #endregion

                //获取供应商相关附件数据
                var fileData = await GetSupplierFilesListAsync(id);
                result.fileData = fileData.Adapt<List<CommonFileListDto>>();

                #region 累加浏览次数
                entity.ViewCount++;
                await _repository.Context.Updateable(entity)
                    .IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await _mongoDbRepository.UpdateAsync(entity, _suppliers, m => m.Id == entity.Id);
                #endregion

                return TkResult<SupplierInfoDto>.Success(result);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"获取供应商详细信息发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 添加供应商
        /// </summary>
        /// <param name="input">添加供应商请求模型</param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task Add([FromBody] AddSupplierRequestModel input)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;

                if ((await GetSupplierInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                r.MechanismId == mechanismId && r.SupplierName == input.supplierName && r.DeleteMark == null)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0002);
                if ((await GetSupplierInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                r.MechanismId == mechanismId && r.SupplierNo == input.supplierNo && r.DeleteMark == null)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0003);

                var entity = input.Adapt<SuppliersEntity>();
                entity.SharedScope = input.sharedScope.GetHashCode();
                entity.OrganizeId = organizeId;
                entity.MechanismId = mechanismId;

                //保存供应商到sqlserver
                var isOk = await _repository.Context.Insertable(entity)
                   .CallEntityMethod(m => m.Creator()).ExecuteReturnEntityAsync();
                _ = isOk ?? throw YNTKException.Oh(ErrorCode.Supplier0004);

                //保存供应商到mongodb
                entity = isOk;
                var result = await _mongoDbRepository.AddAsync(entity, _suppliers);
                if (!result) throw YNTKException.Oh(ErrorCode.Supplier0005);

                //保存供应商相关附件
                await SaveSupplierFilesAsync(entity.Id, userId, input.fileData);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"添加供应商发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 修改供应商
        /// </summary>
        /// <param name="input">修改供应商请求模型</param>
        /// <returns></returns>
        [HttpPut("update")]
        public async Task UpdateForeignData([FromBody] UpdateSupplierRequestModel input)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                var entity = await GetSupplierInfoAsync(r => r.Id == input.id && r.DeleteMark == null);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0001);
                if (entity.CreatorUserId != userId && authenticationType!="2") throw YNTKException.Oh(ErrorCode.D1016);
                if ((await GetSupplierInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                    r.MechanismId == mechanismId && r.SupplierName == input.supplierName && r.Id!=input.id && r.DeleteMark == null)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0002);
                if ((await GetSupplierInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                r.MechanismId == mechanismId && r.SupplierNo == input.supplierNo && r.Id != input.id && r.DeleteMark == null)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0003);

                entity = input.Mapper(entity);
                entity.SharedScope = input.sharedScope.GetHashCode();
                entity.LastModifyTime = DateTime.Now;
                entity.LastModifyUserId = userId;

                //保存供应商到sqlserver
                var isOK = await _repository.Context.Updateable(entity)
               .IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                if (!(isOK > 0)) throw YNTKException.Oh(ErrorCode.Supplier0006);

                //保存供应商到mongodb
                var update = await _mongoDbRepository.UpdateAsync(entity, _suppliers, m => m.Id == entity.Id);
                if (!(update.ModifiedCount > 0)) throw YNTKException.Oh(ErrorCode.Supplier0007);

                //保存供应商相关附件
                await SaveSupplierFilesAsync(entity.Id, userId, input.fileData);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"修改供应商发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 删除供应商
        /// </summary>
        /// <param name="id">供应商id</param>
        /// <returns></returns>
        [HttpDelete("delete/{id}")]
        public async Task Delete([Required] string id)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                var entity = await GetSupplierInfoAsync(r => r.Id == id && r.DeleteMark == null);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0001);
                if (entity.CreatorUserId != userId && authenticationType!="2") throw YNTKException.Oh(ErrorCode.D1016);

                //从sqlserver中删除
                var isOk = await _repository.Context.Deleteable(entity).ExecuteCommandAsync();
                if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Supplier0010);

                //从mongodb中删除
                var delete = await _mongoDbRepository.DeleteAsync(_suppliers, m => m.Id == id);
                if (!(delete > 0)) throw YNTKException.Oh(ErrorCode.Supplier0011);

                //删除供应商相关附件
                await DeleteSupplierFilesAsync(id);
                //删除供应商产品数据
                await DeleteProductAsync(id);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"删除供应商发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 更新供应商状态(启用/禁用)
        /// </summary>
        /// <param name="id">供应商id</param>
        /// <returns></returns>
        [HttpPut("state/{id}")]
        public async Task UpdateState([Required] string id)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                var entity = await GetSupplierInfoAsync(r => r.Id == id && r.DeleteMark == null);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0001);
                if (entity.CreatorUserId != userId && authenticationType!="2") throw YNTKException.Oh(ErrorCode.D1016);

                //sqlserver更新供应商状态
                var isOk = await _repository.Context.Updateable<SuppliersEntity>()
               .SetColumns(it => new SuppliersEntity()
               {
                   EnabledMark = SqlFunc.IIF(it.EnabledMark == 1, 0, 1),
                   LastModifyUserId = userId,
                   LastModifyTime = SqlFunc.GetDate()
               }).Where(it => it.Id == id).ExecuteCommandAsync();
                if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Supplier0008);

                //mongodb更新供应商状态
                entity.EnabledMark = entity.EnabledMark == 1 ? 0 : 1;
                entity.LastModifyTime = DateTime.Now;
                entity.LastModifyUserId = userId;
                var update = await _mongoDbRepository.UpdateAsync(entity, _suppliers, m => m.Id == entity.Id);
                if (!(update.ModifiedCount > 0)) throw YNTKException.Oh(ErrorCode.Supplier0009);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"更新外来资料状态(启用/禁用)发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 根据条件获取供应商信息
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        private async Task<SuppliersEntity> GetSupplierInfoAsync(Expression<Func<SuppliersEntity, bool>> where)
        {
            //从从mongodb中获取
            var entity = await _mongoDbRepository.GetAsync(_suppliers, where);
            //再从sqlserver中获取
            if (entity == null) entity = await _repository.FirstOrDefaultAsync(where);
            return entity;
        }

        /// <summary>
        /// 根据条件获取供应商数据
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        private async Task<List<SuppliersEntity>> GetSupplierListAsync(Expression<Func<SuppliersEntity, bool>> where)
        {
            //从从mongodb中获取
            var result = await _mongoDbRepository.GetListAsync(_suppliers, where);
            //再从sqlserver中获取
            if (!result.Any()) result = await _repository.Entities.Where(where).ToListAsync();
            return result;
        }
        #endregion

        #region 供应商相关附件
        /// <summary>
        /// 获取供应商相关附件数据
        /// </summary>
        /// <param name="supplierId">供应商id</param>
        /// <returns></returns>
        private async Task<List<SupplierFilesEntity>> GetSupplierFilesListAsync(string supplierId)
        {
            //从mongodb中获取附件数据
            var result = await _fileMongoDbRepository.GetListAsync(_supplierfiles, r => r.SupplierId == supplierId);
            if (!result.Any())
            {
                //从sqlserver数据库中获取附件数据
                result = await _fileRepository.Entities.Where(r => r.SupplierId == supplierId).ToListAsync();
            }
            return result;
        }

        /// <summary>
        /// 保存供应商相关附件
        /// </summary>
        /// <param name="supplierId">供应商id</param>
        /// <param name="userId">当前用户id</param>
        /// <param name="fileData">相关附件数据</param>
        /// <returns></returns>
        private async Task SaveSupplierFilesAsync(string supplierId, string userId, List<CommonFileRequestModel> fileData)
        {
            try
            {
                _fileRepository.Ado.BeginTran();
                //删除原数据
                await _fileMongoDbRepository.DeleteAsync(_supplierfiles, r => r.SupplierId == supplierId);
                await _fileRepository.DeleteAsync(r => r.SupplierId == supplierId);
                if (fileData != null && fileData.Count > 0)
                {
                    var files = new List<SupplierFilesEntity>();
                    var file = new SupplierFilesEntity();
                    fileData.ForEach(item =>
                    {
                        file = item.Adapt<SupplierFilesEntity>();
                        file.Id = YitIdHelper.NextId().ToString();
                        file.SupplierId = supplierId;
                        file.CreatorUserId = userId;
                        file.CreatorTime = DateTime.Now;
                        files.Add(file);
                    });
                    //保存到sqlserver                 
                    var isOk = await _fileRepository.Context.Insertable(files).ExecuteCommandAsync();
                    if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Supplier0012);
                    //保存到mongodb
                    var succeed = await _fileMongoDbRepository.AddListAsync(files, _supplierfiles);
                    if (!succeed) throw YNTKException.Oh(ErrorCode.Supplier0013);
                }
                _fileRepository.Ado.CommitTran();
            }
            catch (Exception ex)
            {
                _fileRepository.Ado.RollbackTran();
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"保存供应商相关附件发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 删除供应商相关附件数据
        /// </summary>
        /// <param name="supplierId">供应商id</param>
        /// <returns></returns>
        private async Task DeleteSupplierFilesAsync(string supplierId)
        {
            var result = await GetSupplierFilesListAsync(supplierId);
            if (result.Any())
            {
                //删除原数据
                await _fileMongoDbRepository.DeleteAsync(_supplierfiles, r => r.SupplierId == supplierId);
                await _fileRepository.DeleteAsync(r => r.SupplierId == supplierId);
                //删除文件
                var deleteFiles = result.Adapt<List<FileListDto>>();
                _fileService.DeleteFiles(deleteFiles);
            }
        }
        #endregion

        #region 供应商评价
        /// <summary>
        /// 获取评价类型
        /// </summary>
        /// <returns></returns>
        [HttpGet("evaluates/evaluatetype")]
        public TkResult<List<EnumListDto>> GetEvaluateTypeList()
        {
            Dictionary<int, string> dic = EnumHelper.EnumToDic<EvaluateTypeEnum>();
            var result = new List<EnumListDto>();
            foreach (KeyValuePair<int, string> kv in dic)
            {
                result.Add(new EnumListDto { Id = kv.Key.ToStr(), Value = kv.Key, Description = kv.Value });
            }
            return TkResult<List<EnumListDto>>.Success(result);
        }

        /// <summary>
        /// 获取供应商评价数量(全部、好评、中评、差评)
        /// </summary>
        /// <param name="supplierId"></param>
        /// <returns></returns>
        [HttpGet("evaluates/count/{supplierId}")]
        public async Task<TkResult<List<EnumListDto>>> GetCount([Required] string supplierId)
        {
            var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
            string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
            Dictionary<int, string> dic = EnumHelper.EnumToDic<EvaluateTypeEnum>();
            var result = new List<EnumListDto>();
            int count = (int)await GetCountAsync(r => r.OrganizeId == organizeId && r.SupplierId == supplierId);
            result.Add(new EnumListDto { Id = null, Value = count, Description = "全部" });
            foreach (KeyValuePair<int, string> kv in dic)
            {
                count = (int)await GetCountAsync(r=>r.OrganizeId== organizeId && r.SupplierId== supplierId && r.Type== kv.Key);
                result.Add(new EnumListDto { Id = kv.Key.ToStr(), Value = count, Description = kv.Value });
            }
            return TkResult<List<EnumListDto>>.Success(result);
        }

        /// <summary>
        /// 分页获取供应商评价数据
        /// </summary>
        /// <param name="query">查询供应商评价请求模型</param>
        /// <returns></returns>
        [HttpPost("evaluates/gets")]
        public async Task<TkPageResult<SupplierEvaluateListDto>> GetEvaluateList([FromBody] QuerySupplierEvaluateFilterRequestModel query)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;

                #region 拼接查询条件
                Expression<Func<SupplierEvaluateEntity, bool>> where = m => 
                m.OrganizeId == organizeId && m.SupplierId==query.supplierId;
                if (!string.IsNullOrWhiteSpace(query.mechanismId))
                {
                    string queryMechanismId = await _mechanismService.GetIdAsync(query.mechanismId, organizeId);
                    where = where.And(m => m.MechanismId == queryMechanismId);
                }
                if (query.type != null) where = where.And(m=>m.Type==query.type.GetHashCode());
                if (query.startTime != null) where = where.And(m => m.CreatorTime >= query.startTime);
                if (query.endTime != null) where = where.And(m => m.CreatorTime <= query.endTime);
                #endregion

                var pageList = new SqlSugarPagedList<SupplierEvaluateListDto>();

                #region 先从mongodb中获取供应商评价数据
                //排序生成器
                var builderSort = Builders<SupplierEvaluateEntity>.Sort;
                //排序约束   Ascending 正序    Descending 倒序
                var sort = builderSort.Descending(r => r.CreatorTime);
                //Item1.结果集 Item2.总条数 Item3.总页数
                (List<SupplierEvaluateEntity>, int, int) result =
                    await _evaluatemongoDbRepository.GetListAsync(_supplier_evaluates,
                    where, query.currentPage, query.pageSize, null, sort);
                pageList.list = result.Item1.Adapt<List<SupplierEvaluateListDto>>();
                pageList.pagination = new PagedModel()
                {
                    PageIndex = query.currentPage,
                    PageSize = query.pageSize,
                    Total = result.Item2,
                    PageCount = result.Item3
                };
                #endregion

                if (!pageList.list.Any())
                {
                    #region 再从sqlserver中获取供应商评价数据
                    var sqlResult = await _evaluateRepository.Entities.Where(where)
                        .OrderBy(r => r.CreatorTime, OrderByType.Desc)
                        .ToPagedListAsync(query.currentPage, query.pageSize);
                    pageList.list = sqlResult.list.Adapt<List<SupplierEvaluateListDto>>();
                    pageList.pagination = sqlResult.pagination;
                    #endregion
                }

                #region 处理供应商评价返回数据
                if (pageList.list.Any())
                {
                    var mechanismIds = pageList.list.Where(r => !string.IsNullOrWhiteSpace(r.mechanismId))
                        ?.Select(r => r.mechanismId.Split(',').ToList())
                        ?.SelectMany(r => r).Distinct().ToList();
                    var mechanisms = !mechanismIds.Any() ? new List<MechanismEntity>() :
                        await _mechanismService.GetMechanismListAsync(null, mechanismIds);
                    var userIds = pageList.list.Select(r => r.creatorUserId).Distinct().ToList();
                    var users = await _tkUsersService.GetUserListByIds(userIds);
                    pageList.list.ForEach(item =>
                    {
                        item.typeText = EnumHelper.GetEnumDescriptionString
                        (item.type, typeof(EvaluateTypeEnum));
                        if (!string.IsNullOrWhiteSpace(item.mechanismId))
                            item.mechanismName = mechanisms?.FirstOrDefault(r => r.Id == item.mechanismId.Split(',').Last())?.Name;
                        item.creatorUserName = users?.FirstOrDefault(r => r.Id == item.creatorUserId)?.RealName;
                    });
                }
                #endregion

                return TkPageResult<SupplierEvaluateListDto>.Success(pageList);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"分页获取供应商评价数据发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 添加供应商评价
        /// </summary>
        /// <param name="input">添加供应商评价请求模型</param>
        /// <returns></returns>
        [HttpPost("evaluates/add")]
        public async Task AddEvaluate([FromBody] AddSupplierEvaluateRequestModel input)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;

                var supplier = await GetSupplierInfoAsync(r => r.Id == input.supplierId && r.DeleteMark == null);
                _ = supplier ?? throw YNTKException.Oh(ErrorCode.Supplier0001);
               
                var entity = new SupplierEvaluateEntity();
                entity.Id = YitIdHelper.NextId().ToString();
                entity.CreatorUserId = userId;
                entity.CreatorTime = DateTime.Now;
                entity.OrganizeId = organizeId;
                entity.MechanismId = mechanismId;
                entity.Type = input.type.GetHashCode();
                entity.SupplierId = input.supplierId;
                entity.Description = input.description;

                //保存供应商评价到sqlserver
                var isOk = await _evaluateRepository.Context.Insertable(entity).ExecuteReturnEntityAsync();
                _ = isOk ?? throw YNTKException.Oh(ErrorCode.Supplier0029);

                //保存供应商评价到mongodb
                var result = await _evaluatemongoDbRepository.AddAsync(entity, _supplier_evaluates);
                if (!result) throw YNTKException.Oh(ErrorCode.Supplier0030);              
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"添加供应商评价发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 删除供应商评价
        /// </summary>
        /// <param name="id">评价id</param>
        /// <returns></returns>
        [HttpDelete("evaluates/delete{id}")]
        public async Task DeleteEvaluate([Required] string id)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                var entity = await GetEvaluateInfoAsync(r => r.Id == id);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0031);
                if (entity.CreatorUserId != userId && authenticationType != "2")
                    throw YNTKException.Oh(ErrorCode.D1016);

                //从sqlserver中删除
                var isOk = await _evaluateRepository.DeleteAsync(r => r.Id == id);
                if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Supplier0032);

                //从mongodb中删除
                var delete = await _evaluatemongoDbRepository.DeleteAsync(_supplier_evaluates, m => m.Id == id);
                if (!(delete > 0)) throw YNTKException.Oh(ErrorCode.Supplier0033);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"删除供应商评价发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 根据条件获取供应商评价信息
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        private async Task<SupplierEvaluateEntity> GetEvaluateInfoAsync(Expression<Func<SupplierEvaluateEntity, bool>> where)
        {
            //从从mongodb中获取
            var entity = await _evaluatemongoDbRepository.GetAsync(_supplier_evaluates, where);
            //再从sqlserver中获取
            if (entity == null) entity = await _evaluateRepository.FirstOrDefaultAsync(where);
            return entity;
        }

        /// <summary>
        /// 根据条件获取接收供应商评价数量
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        private async Task<long> GetCountAsync(Expression<Func<SupplierEvaluateEntity, bool>> where)
        {
            long count = await _evaluatemongoDbRepository.CountAsync(_supplier_evaluates, where);
            if (!(count > 0)) count = await _evaluateRepository.CountAsync(where);
            return count;
        }
        #endregion

        #region 产品清单
        /// <summary>
        /// 获取供应商产品下拉数据(只获取启用的),查询全部：“api/suppliers/products/selects/{supplierId}/null”
        /// </summary>
        /// <param name="supplierId">供应商id,必传</param>
        /// <param name="classifyId">产品分类id</param>
        /// <returns></returns>
        [HttpGet("products/selects/{supplierId}/{classifyId}")]
        public async Task<TkResult<List<SupplierProductSelectDto>>> GetProductSelect([Required] string supplierId,string classifyId)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;

                #region 拼接查询条件
                Expression<Func<SupplierProductLibraryEntity, bool>> where = m => 
                m.OrganizeId == organizeId && m.SupplierId== supplierId && m.EnabledMark==1;
                if (!string.IsNullOrWhiteSpace(classifyId))
                {
                    string queryClassifyId = await _dictionaryService.GetIdAsync(classifyId, organizeId);
                    where = where.And(m => m.ClassifyId == queryClassifyId);
                }
                #endregion

                var data = await GetProductListAsync(where);
                var result = data.Adapt<List<SupplierProductSelectDto>>();
                return TkResult<List<SupplierProductSelectDto>>.Success(result);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"获取供应商产品下拉数据发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 分页获取供应商产品清单数据
        /// </summary>
        /// <param name="query">查询供应商产品清单请求模型</param>
        /// <returns></returns>
        [HttpPost("products/gets")]
        public async Task<TkPageResult<SupplierProductListDto>> GetProductList([FromBody] QuerySupplierProductLibraryFilterRequestModel query)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;

                #region 拼接查询条件
                Expression<Func<SupplierProductLibraryEntity, bool>> where = m =>m.OrganizeId== organizeId;
                if (query.enabledMark == 1) where = where.And(m => m.EnabledMark == 1);
                if (query.enabledMark == 0) where = where.And(m => m.EnabledMark != 1);
                if (!string.IsNullOrWhiteSpace(query.supplierId)) where = where.And(m => m.SupplierId == query.supplierId);
                if (!string.IsNullOrWhiteSpace(query.classifyId))
                {
                    string queryClassifyId = await _dictionaryService.GetIdAsync(query.classifyId, organizeId);
                    where = where.And(m => m.ClassifyId == queryClassifyId);
                }
                if (query.startTime != null) where = where.And(m => m.CreatorTime >= query.startTime);
                if (query.endTime != null) where = where.And(m => m.CreatorTime <= query.endTime);
                if (query.startPrice != null) where = where.And(m => m.ReferencePrice >= query.startPrice);
                if (query.endPrice != null) where = where.And(m => m.ReferencePrice <= query.endPrice);
                if (!string.IsNullOrWhiteSpace(query.keyword))
                    where = where.And(m => m.ProductName.Contains(query.keyword) ||
                    m.ProductNo.Contains(query.keyword) || m.Specification.Contains(query.keyword) ||
                    m.LabelTag.Contains(query.keyword) || m.PlaceOrigin.Contains(query.keyword));
                #endregion

                var pageList = new SqlSugarPagedList<SupplierProductListDto>();

                #region 先从mongodb中获取供应商产品清单数据
                //排序生成器
                var builderSort = Builders<SupplierProductLibraryEntity>.Sort;
                //排序约束   Ascending 正序    Descending 倒序
                var sort = builderSort.Ascending(r => r.SortCode).Descending(r => r.CreatorTime);
                //Item1.结果集 Item2.总条数 Item3.总页数
                (List<SupplierProductLibraryEntity>, int, int) result =
                    await _productMongoDbRepository.GetListAsync(_productlibrary,
                    where, query.currentPage, query.pageSize, null, sort);
                pageList.list = result.Item1.Adapt<List<SupplierProductListDto>>();
                pageList.pagination = new PagedModel()
                {
                    PageIndex = query.currentPage,
                    PageSize = query.pageSize,
                    Total = result.Item2,
                    PageCount = result.Item3
                };
                #endregion

                if (!pageList.list.Any())
                {
                    #region 再从sqlserver中获取供应商产品清单数据
                    var sqlResult = await _productRepository.Entities.Where(where)
                        .OrderBy(r => r.SortCode, OrderByType.Asc)
                        .OrderBy(r => r.CreatorTime, OrderByType.Desc)
                        .ToPagedListAsync(query.currentPage, query.pageSize);
                    pageList.list = sqlResult.list.Adapt<List<SupplierProductListDto>>();
                    pageList.pagination = sqlResult.pagination;
                    #endregion
                }

                #region 处理产品清单返回数据
                if (pageList.list.Any())
                {
                    var supplierIds = pageList.list.Select(r => r.supplierId).Distinct().ToList();
                    var suppliers = await GetSupplierListAsync(r=> supplierIds.Contains(r.Id));
                    var classifyIds = pageList.list.Select(r => r.classifyId.Split(',').ToList())
                       .SelectMany(r => r).Distinct().ToList();
                    var classifys = await _dictionaryService.GetDictionaryListByIds(classifyIds);
                    var userIds = pageList.list.Select(r => r.creatorUserId).Distinct().ToList();
                    var users = await _tkUsersService.GetUserListByIds(userIds);
                    pageList.list.ForEach(item =>
                    {
                        if(!string.IsNullOrWhiteSpace(item.supplierId))
                            item.supplierName = suppliers?.FirstOrDefault(r => r.Id == item.supplierId)?.SupplierName;
                        if (!string.IsNullOrWhiteSpace(item.classifyId))
                            item.classifyName = classifys?.FirstOrDefault(r => r.Id == item.classifyId.Split(',').Last())?.Name;
                        item.creatorUserName = users?.FirstOrDefault(r => r.Id == item.creatorUserId)?.RealName;
                        if (!string.IsNullOrWhiteSpace(item.labelTag)) item.tags = item.labelTag.Split('|').ToList();
                    });
                }
                #endregion

                return TkPageResult<SupplierProductListDto>.Success(pageList);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"分页获取供应商数据发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 获取供应商产品详细信息
        /// </summary>
        /// <param name="id">产品id</param>
        /// <returns></returns>
        [HttpGet("products/get/{id}")]
        public async Task<TkResult<SupplierProductInfoDto>> GetProductInfo([Required] string id)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                var entity = await GetProductInfoAsync(r => r.Id == id);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0014);

                var result = entity.Adapt<SupplierProductInfoDto>();

                #region 处理供应商产品返回信息
                result.supplierName = (await GetSupplierInfoAsync(r => r.Id == result.supplierId))?.SupplierName;
                if (!string.IsNullOrWhiteSpace(result.classifyId))
                {
                    result.classifyName = string.Join('/', (await _dictionaryService
                   .GetDictionaryListByIds(result.classifyId.Split(',').ToList()))
                   ?.Select(r => r.Name)?.ToList());
                }
                if (!string.IsNullOrWhiteSpace(result.creatorUserId))
                    result.creatorUserName = (await _tkUsersService.GetUserInfoByUserId(result.creatorUserId))?.RealName;
                if (!string.IsNullOrWhiteSpace(result.labelTag)) result.tags = result.labelTag.Split('|').ToList();
                var info = await GetProductDetailAsync(r=>r.Id ==id);
                if (info != null)
                {
                    result.pictureFiles = info.PictureFiles;
                    if (!string.IsNullOrWhiteSpace(info.PictureFiles))
                        result.pictureFilePaths = info.PictureFiles.Split('|').ToList();
                    result.content = info.Content;
                }
                #endregion

                #region 累加浏览次数
                entity.ViewCount++;
                await _productRepository.Context.Updateable(entity).WhereColumns(it => new { it.Id }).ExecuteCommandAsync();
                await _productMongoDbRepository.UpdateAsync(entity, _productlibrary, m => m.Id == entity.Id);
                #endregion

                return TkResult<SupplierProductInfoDto>.Success(result);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"获取供应商产品详细信息发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 添加供应商产品
        /// </summary>
        /// <param name="input">添加供应商产品请求模型</param>
        /// <returns></returns>
        [HttpPost("products/add")]
        public async Task AddProduct([FromBody] AddSupplierProductRequestModel input)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;

                var supplier = await GetSupplierInfoAsync(r => r.Id == input.supplierId && r.DeleteMark == null);
                _ = supplier ?? throw YNTKException.Oh(ErrorCode.Supplier0001);
                if ((await GetProductInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                r.MechanismId == mechanismId && r.ProductName == input.productName)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0015);
                if ((await GetProductInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                r.MechanismId == mechanismId && r.ProductNo == input.productNo)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0016);

                var entity = input.Adapt<SupplierProductLibraryEntity>();
                entity.Id= YitIdHelper.NextId().ToString();
                entity.CreatorUserId = userId;
                entity.CreatorTime = DateTime.Now;
                entity.OrganizeId = organizeId;
                entity.MechanismId = mechanismId;
                if (entity.EnabledMark == null) entity.EnabledMark = 1;
                if (input.tags != null && input.tags.Count > 0) entity.LabelTag = string.Join('|',input.tags);

                //保存供应商产品到sqlserver
                var isOk = await _productRepository.Context.Insertable(entity).ExecuteReturnEntityAsync();
                _ = isOk ?? throw YNTKException.Oh(ErrorCode.Supplier0017);

                //保存供应商产品到mongodb
                var result = await _productMongoDbRepository.AddAsync(entity, _productlibrary);
                if (!result) throw YNTKException.Oh(ErrorCode.Supplier0018);

                //保存供应商产品详细信息到sqlserver
                var detail = new SupplierProductLibraryDetailEntity();
                detail.Id = entity.Id;
                detail.ProductId = entity.Id;
                if (input.pictureFilePaths != null && input.pictureFilePaths.Count > 0)
                    detail.PictureFiles = string.Join('|', input.pictureFilePaths);
                detail.Content = input.content;
                var add = await _productDetailRepository.Context.Insertable(detail).ExecuteReturnEntityAsync();
                _ = isOk ?? throw YNTKException.Oh(ErrorCode.Supplier0019);
                //保存供应商产品详细信息到mongodb
                result = await _productDetailMongoDbRepository.AddAsync(detail, _productlibrary_details);
                if (!result) throw YNTKException.Oh(ErrorCode.Supplier0020);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"添加供应商产品发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 修改供应商产品信息
        /// </summary>
        /// <param name="input">修改供应商产品信息请求模型</param>
        /// <returns></returns>
        [HttpPut("products/update")]
        public async Task UpdateProduct([FromBody] UpdateSupplierProductRequestModel input)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                string organizeId = user.Subject.FindFirst(ClaimConst.ORGANIZEID).Value;
                string mechanismId = user.Subject.FindFirst(ClaimConst.MECHANISMID).Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                var supplier = await GetSupplierInfoAsync(r => r.Id == input.supplierId && r.DeleteMark == null);
                _ = supplier ?? throw YNTKException.Oh(ErrorCode.Supplier0001);
                var entity= await GetProductInfoAsync(r => r.Id == input.id);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0014);
                if (entity.CreatorUserId != userId && authenticationType != "2") throw YNTKException.Oh(ErrorCode.D1016);
                if ((await GetProductInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                    r.MechanismId == mechanismId && r.ProductName == input.productName && r.Id != input.id)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0015);
                if ((await GetProductInfoAsync(r => r.OrganizeId == organizeId && r.ClassifyId == input.classifyId &&
                r.MechanismId == mechanismId && r.ProductNo == input.productNo && r.Id != input.id)) != null)
                    throw YNTKException.Oh(ErrorCode.Supplier0016);

                entity = input.Mapper(entity);
                if (entity.EnabledMark == null) entity.EnabledMark = 1;
                if (input.tags != null && input.tags.Count > 0) entity.LabelTag = string.Join('|', input.tags);

                //保存供应商产品到sqlserver
                var isOK = await _productRepository.Context.Updateable(entity)
                       .WhereColumns(it => new { it.Id }).ExecuteCommandAsync();
                if (!(isOK > 0)) throw YNTKException.Oh(ErrorCode.Supplier0021);

                //保存供应商产品到mongodb
                var update = await _productMongoDbRepository.UpdateAsync(entity, _productlibrary, m => m.Id == entity.Id);
                if (!(update.ModifiedCount > 0)) throw YNTKException.Oh(ErrorCode.Supplier0022);

                //保存供应商产品详细信息到sqlserver
                var detail = await GetProductDetailAsync(r=>r.Id==entity.Id);
                if (input.pictureFilePaths != null && input.pictureFilePaths.Count > 0)
                    detail.PictureFiles = string.Join('|', input.pictureFilePaths);
                detail.Content = input.content;
                isOK = await _productDetailRepository.Context.Updateable(detail)
                       .WhereColumns(it => new { it.Id }).ExecuteCommandAsync();
                if (!(isOK > 0)) throw YNTKException.Oh(ErrorCode.Supplier0019);
                //保存供应商产品详细信息到mongodb
                update = await _productDetailMongoDbRepository.UpdateAsync(detail, _productlibrary_details, m => m.Id == entity.Id);
                if (!(update.ModifiedCount > 0)) throw YNTKException.Oh(ErrorCode.Supplier0020);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"修改供应商产品信息发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 删除供应商产品
        /// </summary>
        /// <param name="id">产品id</param>
        /// <returns></returns>
        [HttpDelete("products/delete/{id}")]
        public async Task DeleteProduct([Required] string id)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                var entity = await GetProductInfoAsync(r => r.Id == id);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0014);
                if (entity.CreatorUserId != userId && authenticationType != "2") 
                    throw YNTKException.Oh(ErrorCode.D1016);

                //从sqlserver中删除
                var isOk = await _productRepository.DeleteAsync(r=>r.Id==id);
                if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Supplier0023);

                //从mongodb中删除
                var delete = await _productMongoDbRepository.DeleteAsync(_productlibrary, m => m.Id == id);
                if (!(delete > 0)) throw YNTKException.Oh(ErrorCode.Supplier0024);

                var detail = await GetProductDetailAsync(r => r.Id == entity.Id);
                if (detail != null)
                {
                    //从sqlserver中删除供应商产品详细信息
                    isOk = await _productDetailRepository.DeleteAsync(r=>r.Id==id);
                    if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Supplier0025);
                    //从mongodb中删除供应商产品详细信息
                    delete = await _productDetailMongoDbRepository.DeleteAsync(_productlibrary_details, m => m.Id == id);
                    if (!(delete > 0)) throw YNTKException.Oh(ErrorCode.Supplier0026);
                }
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"删除供应商产品发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 更新供应商产品(启用/禁用)
        /// </summary>
        /// <param name="id">产品id</param>
        /// <returns></returns>
        [HttpPut("products/state/{id}")]
        public async Task UpdateProductState([Required] string id)
        {
            try
            {
                var user = _httpContext.User.FindFirst(ClaimConst.CLAINM_USERID);
                string userId = user.Value;
                //账号类型【0.平台运营人员 1.超级管理员 2.组织管理员 3.组织用户 4.第三方登录用户 5.游客用户】
                var authenticationType = user.Subject.FindFirst(ClaimConst.ACCOUNTTYPE).Value;

                var entity = await GetProductInfoAsync(r => r.Id == id);
                _ = entity ?? throw YNTKException.Oh(ErrorCode.Supplier0014);
                if (entity.CreatorUserId != userId && authenticationType != "2")
                    throw YNTKException.Oh(ErrorCode.D1016);

                //sqlserver更新供应商产品状态
                var isOk = await _productRepository.Context.Updateable<SupplierProductLibraryEntity>()
               .SetColumns(it => new SupplierProductLibraryEntity()
               {
                   EnabledMark = SqlFunc.IIF(it.EnabledMark == 1, 0, 1),
               }).Where(it => it.Id == id).ExecuteCommandAsync();
                if (!(isOk > 0)) throw YNTKException.Oh(ErrorCode.Supplier0027);

                //mongodb更新供应商产品状态
                entity.EnabledMark = entity.EnabledMark == 1 ? 0 : 1;
                var update = await _productMongoDbRepository.UpdateAsync(entity, _productlibrary, m => m.Id == entity.Id);
                if (!(update.ModifiedCount > 0)) throw YNTKException.Oh(ErrorCode.Supplier0028);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("[")) throw YNTKException.Oh($"{ex.Message}");
                throw YNTKException.Oh($"更新供应商产品(启用/禁用)发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 删除供应商产品
        /// </summary>
        /// <param name="supplierId">供应商id</param>
        /// <returns></returns>
        private async Task DeleteProductAsync(string supplierId)
        {
            var data =await GetProductListAsync(r=>r.SupplierId== supplierId);
            if (data.Any())
            {
                var ids = data.Select(r => r.Id).ToList();
                //从sqlserver中删除供应商产品数据
                await _productRepository.DeleteAsync(r => r.SupplierId == supplierId);
                //从mongodb中删除供应商产品数据
                await _productMongoDbRepository.DeleteAsync(_productlibrary, m => m.SupplierId == supplierId);
                //从sqlserver中删除供应商产品详细信息数据
                await _productDetailRepository.DeleteAsync(r =>ids.Contains(r.Id));
                //从mongodb中删除供应商产品详细信息数据
                await _productDetailMongoDbRepository.DeleteAsync(_productlibrary_details,m=>ids.Contains(m.Id));
            }           
        }

        /// <summary>
        /// 根据条件获取产品信息
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        private async Task<SupplierProductLibraryEntity> GetProductInfoAsync(Expression<Func<SupplierProductLibraryEntity, bool>> where)
        {
            //从从mongodb中获取
            var entity = await _productMongoDbRepository.GetAsync(_productlibrary, where);
            //再从sqlserver中获取
            if (entity == null) entity = await _productRepository.FirstOrDefaultAsync(where);
            return entity;
        }

        /// <summary>
        /// 根据条件获取产品数据
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        private async Task<List<SupplierProductLibraryEntity>> GetProductListAsync(Expression<Func<SupplierProductLibraryEntity, bool>> where)
        {
            //从从mongodb中获取
            var entity = await _productMongoDbRepository.GetListAsync(_productlibrary, where);
            //再从sqlserver中获取
            if (entity == null) entity = await _productRepository.Entities.Where(where).ToListAsync();
            return entity;
        }

        /// <summary>
        /// 根据条件获取产品详情信息
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        private async Task<SupplierProductLibraryDetailEntity> GetProductDetailAsync(Expression<Func<SupplierProductLibraryDetailEntity, bool>> where)
        {
            //从从mongodb中获取
            var entity = await _productDetailMongoDbRepository.GetAsync(_productlibrary_details, where);
            //再从sqlserver中获取
            if (entity == null) entity = await _productDetailRepository.FirstOrDefaultAsync(where);
            return entity;
        }
        #endregion

    }
}
